package com.kedll.library.crop;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.design.widget.BottomSheetDialog;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.kedll.library.R;
import com.kedll.library.addimg.AddImgFragmentActivity01;
import com.kedll.library.util.GetPathFromUri4kitkat;
import com.kedll.library.util.Parse;
import com.kedll.library.util.ToastUtil;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 从相册或相机中获取图片，要是实现此功能个，必须在Activity中实现onActivityResult方法，并调用TakePhotoHelper对象的onActivityResult方法
 *
 * @author cyt
 */
public class TakePhotoHelper {
    /**
     * 请求相机返回
     */
    public static final int TAKE_PICTURE = 3023;
    /**
     * 请求相册返回
     */
    public static final int PHOTO_PICKED_WITH_DATA = 3021;
    /**
     *
     */
    private static final int PHOTO_RESULT = 3022;

    /**
     * 请求视频返回
     */
    private static final int TAKE_VIDEO = 3204;
//    private File file;

    private Activity activity;
    private Uri mMediaUri;
    private OnTakePhotoCompleteListener completeListener;
    private ArrayList<Map<String, Object>> imagesDatas;
    private boolean isCrop = true;
    private int maxWidth;
    private int maxHeight;
    private int x = 1;
    private int y = 1;
    private OnCancelListener onCancelListener;

    /**
     * 构造方法
     *
     * @param activity 上下文
     */
    public TakePhotoHelper(Activity activity) {
        this.activity = activity;
        imagesDatas = new ArrayList<>();
    }

    /**
     * 把ImageView中的图片转成字符串
     *
     * @param view
     * @return
     */
    public static String Bitmap2Bytes(ImageView view) throws UnsupportedEncodingException {
        return Bitmap2Bytes(getBitmap(view));
    }

    /**
     * 把图片转成字符串
     *
     * @param bm
     * @return
     */
    public static String Bitmap2Bytes(Bitmap bm) throws UnsupportedEncodingException {
        if (bm == null) {
            return null;
        }
        return encodeBase64File(bm);
    }

    public static Bitmap getBitmap(ImageView view) {
        Drawable drawable = view.getDrawable();
        if (checkBitmap(drawable)) {
            return ((BitmapDrawable) drawable).getBitmap();
        }
        return null;
    }

    public static String encodeBase64File(Bitmap bmp) throws UnsupportedEncodingException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        return new String(Base64.encode(baos.toByteArray(), 0), "utf-8");
    }

    public static boolean checkBitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            if (((BitmapDrawable) drawable).getBitmap() == null) {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setOnCancelListener(OnCancelListener onCancelListener) {
        this.onCancelListener = onCancelListener;
    }

    /**
     * 设置图片的最大宽度
     *
     * @param maxWidth 图片的最大宽度
     */
    public void setMaxWidth(int maxWidth) {
        this.maxWidth = maxWidth;
    }

    /**
     * 设置图片的最大高度
     *
     * @param maxHeight 图片的最大高度
     */
    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
    }

    /**
     * 设置是否需要裁剪
     *
     * @param isCrop true 需要裁剪 false 不需要
     */
    public void setIsCrop(boolean isCrop) {
        this.isCrop = isCrop;
    }

    /**
     * 设置获取图片回调
     *
     * @param l 图片回调接口
     */
    public void setOnTakePhotoCompleteListener(OnTakePhotoCompleteListener l) {
        this.completeListener = l;
    }

    public void initImageDatas(Map<String, Object> imgUrl) {
        imagesDatas.add(imgUrl);
    }


    public void removeImage(Map<String, Object> imgUrl) {
        imagesDatas.remove(imgUrl);
    }


    public ArrayList<Map<String, Object>> getImagesDatas() {
        return imagesDatas;
    }

    /**
     * 获取本地的视频文件文档
     */
    public void doPickVideoFromGallery() {
        try {
            Crop.pickVideo(activity);
        } catch (ActivityNotFoundException ignored) {

        }
    }

    /**
     * 通过相机获取视频
     */
    public void doTakeVideo() {
        mMediaUri = getOutMediaUri(TAKE_VIDEO);
        if (mMediaUri == null) {
            ToastUtil.showToast("创建视频文件失败");
        }

        Intent intentVideo = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        intentVideo.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//        intentVideo.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 10 * 1024 * 1024);
//        intentVideo.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intentVideo.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intentVideo.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
        ComponentName componentName = intentVideo.resolveActivity(activity.getPackageManager());
        if (componentName != null) {
            activity.startActivityForResult(intentVideo, TAKE_VIDEO);
        }
    }

    /**
     * 获取存储路径
     *
     * @param mediaType 存储类型
     * @return
     */
    private Uri getOutMediaUri(int mediaType) {
        String mediaName;
        File out;
        Uri mediaUri;
        String storageDir;
        if (mediaType == TAKE_PICTURE) {
            //获取图片存储路劲
            mediaName = getPhotoFileName();
            storageDir = FileUtil.getPhotoPath(activity.getApplication(), mediaName);
        } else if (mediaType == TAKE_VIDEO) {
            //获取视频存储路劲
            mediaName = getVideoFileName();
            storageDir = FileUtil.getVideoPath(activity.getApplication(), mediaName);
        } else {
            return null;
        }

        if (storageDir == null) {
            return null;
        }

        out = new File(storageDir);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mediaUri = FileProvider.getUriForFile(activity.getApplication(), activity.getPackageName() + ".provider", out);
        } else {
            mediaUri = Uri.fromFile(out);
        }

        return mediaUri;
    }

    private String getPhotoFileName() {
        return "IMG_" + System.currentTimeMillis() + ".jpg";
    }// 封装请求Gallery的intent

    private String getVideoFileName() {
        return "VIDEO_" + System.currentTimeMillis() + ".mp4";
    }

    /**
     * 处理图片获取结果的方法,需要在调用的Activity或Fragment处的onActivityResult调用此方法
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        switch (requestCode) {
            case Crop.REQUEST_PICK:
            case PHOTO_PICKED_WITH_DATA:
                if (isCrop) {
                    startPhotoZoom(data.getData());
                } else {
                    if (completeListener != null) {
                        List<String> files = new ArrayList<>();
                        String path = GetPathFromUri4kitkat.getPath(activity, data.getData());
                        files.add(path);
                        addImage(path);

                        completeListener.onComplete(files);
                    }
                }
                break;
            case Crop.REQUEST_CROP:
                //图片裁剪返回
                handleCrop(resultCode, data);
                break;
            case Crop.REQUEST_VIDEO: {
                //获取本地视频文件返回
                if (completeListener != null) {
                    List<String> files = new ArrayList<>();
                    String path = GetPathFromUri4kitkat.getPath(activity, data.getData());
                    files.add(path);
                    completeListener.onComplete(files);
                }
            }
            break;

            case TAKE_PICTURE:
                //拍照返回
                if (isCrop) {
                    startPhotoZoom(mMediaUri);
                } else {
                    if (completeListener != null) {
                        List<String> files = new ArrayList<>();
                        files.add(mMediaUri.getPath());
                        addImage(mMediaUri.getPath());
                        completeListener.onComplete(files);
                    }

                    scanFile(mMediaUri);
                }
                break;

            case TAKE_VIDEO: {
                //录制视频返回
                if (completeListener != null) {
                    List<String> files = new ArrayList<>();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        files.add(FileUtil.getVideoDirectory(activity).concat(mMediaUri.getLastPathSegment()));
                    } else {
                        files.add(mMediaUri.getPath());
                    }
                    completeListener.onComplete(files);
                }
                scanFile(mMediaUri);
            }
            break;
            case 5:
                imagesDatas = (ArrayList<Map<String, Object>>) data.getSerializableExtra("selectedList");
                if (completeListener != null) {
                    List<String> files = new ArrayList<>();
                    for (Map<String, Object> selectStr : imagesDatas) {
                        String path = Parse.getInstance().isNull(selectStr.get("imagePath"));
                        files.add(path);

                    }
                    completeListener.onComplete(files);
                }
                break;
            default:
        }
    }

    /**
     * 收缩图片
     *
     * @param uri
     */
    private void startPhotoZoom(Uri uri) {
        String mediaName = getPhotoFileName();
        String storageDir = FileUtil.getPhotoPath(activity.getApplication(), mediaName);
        if (TextUtils.isEmpty(storageDir)) {
            return;
        }
        File outFile = new File(storageDir);
        Uri cropOutUri = Uri.fromFile(outFile);
        if (cropOutUri == null) {
            ToastUtil.showToast("创建图片文件失败");
        }
        Crop.of(uri, cropOutUri).withAspect(x, y).withMaxSize(maxWidth, maxHeight).start(activity);

    }

    private void addImage(String path) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("imagePath", path);
        map.put("isCheck", true);
        imagesDatas.add(map);

    }

    private void handleCrop(int resultCode, Intent result) {
        if (resultCode == Activity.RESULT_OK) {
            if (completeListener != null) {
                List<String> files = new ArrayList<>();
                String path = Crop.getOutput(result).getPath();
                files.add(path);
                addImage(path);
                completeListener.onComplete(files);
            }
        } else if (resultCode == Crop.RESULT_ERROR) {
            Toast.makeText(activity, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    private void scanFile(Uri path) {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(path);
        activity.sendBroadcast(mediaScanIntent);
    }

    /**
     * 销毁,在调用处的Activity或Fragment中onDestroy调用
     */
    public void onDestroy() {
        activity = null;
        completeListener = null;
        imagesDatas.clear();
        imagesDatas = null;
    }

    /**
     * 打开图片浏览器
     */
    public void showPopup() {
        if (activity == null || activity.isFinishing()) {
            return;
        }

        final BottomSheetDialog dialog = new BottomSheetDialog(activity);
        dialog.setCanceledOnTouchOutside(true);
        if (onCancelListener != null) {
            dialog.setOnCancelListener(onCancelListener);
        }
        View root = LayoutInflater.from(activity).inflate(R.layout.le_select_layout, null);
        root.findViewById(R.id.photoBtn).setOnClickListener(v13 -> {
            dialog.dismiss();
            TakePhotoHelper.this.photo();
        });

        root.findViewById(R.id.galleryBtn).setOnClickListener(v12 -> {
            dialog.dismiss();
            TakePhotoHelper.this.doPickPhotoFromGallery();
        });

        root.findViewById(R.id.cancelBtn).setOnClickListener(v1 -> dialog.cancel());
        dialog.setContentView(root);

        dialog.show();


    }

    //请求相机程序
    public void photo() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            doTakePhoto();
        } else {
            ToastUtil.showToast("没有SD卡");
        }
    }

    // 请求Gallery程序
    public void doPickPhotoFromGallery() throws ActivityNotFoundException {
        Crop.pickImage(activity);
    }

    /**
     * 通过相机获取图片
     */
    private void doTakePhoto() {
        mMediaUri = getOutMediaUri(TAKE_PICTURE);
        if (mMediaUri == null) {
            ToastUtil.showToast("创建图片文件失败");
        }
        Intent intentPhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intentPhoto.putExtra("return-data", false);
        intentPhoto.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intentPhoto.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
        // 获取拍照后未压缩的原图片，并保存在uri路径中
        ComponentName componentName = intentPhoto.resolveActivity(activity.getPackageManager());
        if (componentName != null) {
            activity.startActivityForResult(intentPhoto, TAKE_PICTURE);
        }
    }

    /**
     * 图片多选
     *
     * @param maxCount 最多能选的张数
     */
    public void showPopup(final int maxCount) {
        if (imagesDatas != null && imagesDatas.size() >= maxCount) {
            Toast.makeText(activity, "最多只能添加" + maxCount + "张图片", Toast.LENGTH_SHORT).show();
            return;
        }
        if (activity == null || activity.isFinishing()) {
            return;
        }

        final BottomSheetDialog dialog = new BottomSheetDialog(activity);
        dialog.setCanceledOnTouchOutside(true);
        if (onCancelListener != null) {
            dialog.setOnCancelListener(onCancelListener);
        }
        View root = LayoutInflater.from(activity).inflate(R.layout.le_select_layout, null);
        root.findViewById(R.id.photoBtn).setOnClickListener(v -> {
            dialog.dismiss();
            TakePhotoHelper.this.photo();
        });

        root.findViewById(R.id.galleryBtn).setOnClickListener(v -> {
            dialog.dismiss();
            TakePhotoHelper.this.doPickMultiPhotoFrameGallery(maxCount);
        });

        root.findViewById(R.id.cancelBtn).setOnClickListener(v -> dialog.cancel());
        dialog.setContentView(root);

        dialog.show();
    }

    /**
     * 显示选择多张图片
     *
     * @param maxCount
     */
    private void doPickMultiPhotoFrameGallery(int maxCount) {
        Intent intent = new Intent(activity, AddImgFragmentActivity01.class);
        intent.putExtra("maxImg", maxCount);
        intent.putExtra("selectedList", imagesDatas);
        activity.startActivityForResult(intent, 5);
    }

    public interface OnTakePhotoCompleteListener {
        void onComplete(List<String> picStr);
    }
}